﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Net;

namespace CommonUtil
{
    public class FileHandle
    {
        private static string CurrentPath = string.Empty;
        private static string CurrentFullPath = string.Empty;
        static FileHandle()
        {
            CurrentPath = BaseDirectory(); //当前程序主文件所在路径（包括和最末尾的\）
            CurrentFullPath = FileFullName(); //当前程序主文件全路径
        }

        /// <summary>
        /// 判断应用程序根目录下指定文件是否存在
        /// </summary>
        /// <param name="fileName">文件名.扩展名（不包括路径）</param>
        /// <param name="isCreat">不存在时是否新建文件</param>
        /// <returns></returns>
        public static bool IsFileExists(string fileName, bool isCreat)
        {
            string filePath = CurrentPath + fileName;

            if (File.Exists(filePath))
            {
                if (isCreat)
                {
                    filePath = filePath.TrimEnd(); //删除行尾空格
                    FileStream fs = new FileStream(filePath, FileMode.Create);
                    fs.Position = 0;
                }
                return true;
            }
            else return false;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName">文件名.扩展名（不包括路径）</param>
        public static void DeletFile(string fileName)
        {
            if (IsFileExists(fileName, false))
            {
                string filePath = CurrentPath + fileName;
                FileInfo fileInfo = new FileInfo(filePath);
                fileInfo.Delete();
            }
        }
        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="fileName">源文件名.扩展名（不包括路径）</param>
        /// <param name="destFileName">目标文件名.扩展名（不包括路径）</param>
        public static void CopeFile(string fileName, string destFileName)
        {
            if (IsFileExists(fileName, false) && !(IsFileExists(destFileName,false)))
            {
                FileInfo fileInfo = new FileInfo(CurrentPath + fileName);
                fileInfo.CopyTo(CurrentFullPath + destFileName);
            }
        }
        /// <summary>
        /// 备份后删除文件，备份名后缀为.backup
        /// </summary>
        /// <param name="fileName">文件名.扩展名（不包括路径）</param>
        public static void DeleteFileAfterBackup(string fileName)
        {
            if (IsFileExists(fileName, false))
            {
                string filePath = CurrentPath + fileName;
                string bakFilePath = GetFileShortName(filePath) + @".bkp";
                if(IsFileExists(bakFilePath,false))
                {
                    DeletFile(bakFilePath);
                }
                FileInfo fileInfo = new FileInfo(filePath);
                fileInfo.Delete();
                fileInfo.CopyTo(bakFilePath);
            }
        }
        /// <summary>
        /// 删除零字节文件
        /// </summary>
        /// <param name="fileName">文件名.扩展名（不包括路径）</param>
        public static void DeleteZeroFile(string fileName)
        {
            if (IsFileExists(fileName, false))
            {
                string filePath = CurrentPath + fileName;
                FileInfo fileInfo = new FileInfo(filePath);
                if (fileInfo.Length <= 0)
                {
                    fileInfo.Delete();
                }
            }
        }
        /// <summary>
        /// 获取当前程序主文件名（文件名.扩展名）
        /// </summary>
        /// <returns></returns>
        public static string GetFileName()
        {
            return Path.GetFileName(CurrentFullPath);
        }
        /// <summary>
        /// 获取指定文件名
        /// </summary>
        /// <param name="fullPath">文件全路径名</param>
        /// <returns></returns>
        public static string GetFileName(string fullPath)
        {
            if (File.Exists(fullPath))
            {
                return Path.GetFileName(fullPath);
            }
            else
                return string.Empty;
        }
        /// <summary>
        /// 获取扩展名（.扩展名）
        /// </summary>
        /// <returns></returns>
        public static string GetFileExtension()
        {
            return Path.GetExtension(CurrentFullPath);
        }
        /// <summary>
        /// 获取指定文件的扩展名（包括前面的点号）
        /// </summary>
        /// <param name="fullPath">文件全路径名</param>
        /// <returns></returns>
        public static string GetFileExtension(string fullPath)
        {
            return Path.GetExtension(fullPath);
        }
        /// <summary>
        /// 获取程序主文件名（文件名）
        /// </summary>
        /// <returns></returns>
        public static string GetFileShortName()
        {
            return GetFileName().Replace(GetFileExtension(),string.Empty);
        }
        /// <summary>
        /// 获取指定文件的文件名（不包括路径和扩展名）
        /// </summary>
        /// <param name="fullPath">文件全路径名</param>
        /// <returns></returns>
        public static string GetFileShortName(string fullPath)
        {
            return GetFileName(fullPath).Replace(GetFileExtension(fullPath), string.Empty);
        }
        /// <summary>
        /// 获取当前程序主文件版本号（1.0.0.0）
        /// </summary>
        /// <returns></returns>
        public static string GetFileVersion()
        {
            FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(CurrentFullPath);
            return string.Format("{0}.{1}.{2}.{3}", fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart);
        }
        /// <summary>
        /// 获取指定文件版本号（1.0.0.0）
        /// </summary>
        /// <param name="fileFullName">文件全路径名</param>
        /// <returns></returns>
        public static string GetFileVersion(string filePath, string fileName)
        {
            if (File.Exists(filePath + fileName))
            {
                FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(filePath + fileName);
                return string.Format("{0}.{1}.{2}.{3}", fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart);
            }
            else
                return string.Empty;
        }
        /// <summary>
        /// 版本号比较，使用1.0.0.1字符串信息
        /// </summary>
        /// <param name="oldVerStr">要比较的版本号</param>
        /// <param name="newVerStr">当前最新版本号</param>
        /// <returns>0:不需要更新;1:需要更新</returns>
        public static int FileVersionCompare(string oldVerStr, string newVerStr)
        {
            if (oldVerStr.CompareTo(newVerStr) < 0)
            {
                return 1;
            }
            else return 0;
        }

        /// <summary>
        ///  从”文件名.扩展名|版本号“字符串获取文件名
        /// </summary>
        /// <param name="fileNameVersionString">fileName.ext|ver,fileName.ext|Ver,fileName.ext|Ver</param>
        /// <returns>fileName.ext</returns>
        public static ArrayList GetNameFromStringOfFileNameVersion(string fileNameVersionString)
        {
            if(string.IsNullOrEmpty(fileNameVersionString))
            {
                return null;
            }
            ArrayList result = new ArrayList();
            string[] fileNameVersion = fileNameVersionString.Split(new char[] { ',' });
            foreach (string currfnv in fileNameVersion)
            {
                result.Add(currfnv.Split(new char[] { '|' })[0]);
            }
            return result;
        }
        /// <summary>
        /// 从”文件名.扩展名|版本号“字符串获取版本号
        /// </summary>
        /// <param name="fileName">fileName.ext</param>
        /// <param name="fileNameVersionString">fileName.ext|ver,fileName.ext|Ver,fileName.ext|Ver</param>
        /// <returns>ver</returns>
        public static string GetVersionFromStringOfFileNameVersion(string fileName, string fileNameVersionString)
        {
            if (string.IsNullOrEmpty(fileNameVersionString))
            {
                return string.Empty;
            }
            string result = "";
            string[] fileNameVersion = fileNameVersionString.Split(new char[] { ',' });
            foreach (string currfnv in fileNameVersion)
            {
                if (fileName.Equals(currfnv.Split(new char[] { '|' })[0]))
                {
                    result = currfnv.Split(new char[] { '|' })[1];
                    break;
                }
                else
                {
                    continue;
                }
            }
            return result;
        }

        /// <summary>
        /// 比较版本号是否相同
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="oldVerMD5">要比较的文件的源MD5值</param>
        /// <returns></returns>
        public static bool FileVersionEqual(string fileName, string VerMD5)
        {            
            if (VerMD5.Equals(GetFileMD5Hash(fileName)))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 获取当前目录下指定文件的MD5值
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetFileMD5Hash(string fileName)
        {
            if (IsFileExists(fileName, false))
            {
                string filePath = CurrentPath + fileName;
                try
                {
                    FileStream fs = new FileStream(filePath, FileMode.Open);
                    System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                    byte[] retVal = md5.ComputeHash(fs);
                    fs.Close();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0, j = retVal.Length; i < j; i++)
                    {
                        sb.Append(retVal[i].ToString("x2"));
                    }
                    return sb.ToString();
                }
                catch (Exception)
                {
                    return string.Empty;
                }
            }
            else return string.Empty;
        }
        /// <summary>
        /// 获取程序目录下指定后缀名的文件
        /// </summary>
        /// <param name="extName">后缀名，如：.dll</param>
        /// <returns>"文件名.扩展名"列表</returns>
        public static ArrayList GetDllFileName(string extName)
        {
            return GetDllFileName(extName, CurrentPath);
        }

        public static ArrayList GetDllFileName(string extName,string url)
        {
            ArrayList arrList = new ArrayList();
            FileInfo[] fileList;            
            DirectoryInfo dir = new DirectoryInfo(url);
            fileList = dir.GetFiles(@"*" + extName);
            if (fileList.Length > 0)
            {
                foreach (FileInfo info in fileList)
                {
                    if (info.Name.StartsWith("YZ_", StringComparison.Ordinal))
                    {
                        arrList.Add(info.Name);
                    }
                    string fileShortName = info.Name.Replace(extName, "");
                    switch (fileShortName)
                    {
                        case "CommonUtil":
                            arrList.Add(info.Name);
                            break;
                        case "WinFrmCtrlLib":
                            arrList.Add(info.Name);
                            break;
                        default:
                            break;
                    }
                }
            }
            return arrList;
        }

        /// <summary>
        ///  获取指定目录下的指定类型文件列表
        /// </summary>
        /// <param name="dirPath">文件所在目录</param>
        /// <param name="extName">文件扩展名：.dll</param>
        /// <returns>fileName.ext</returns>
        public static ArrayList GetFileNameByExt(string dirPath, string extName)
        {
            ArrayList arrList = new ArrayList();
            FileInfo[] fileList;
            DirectoryInfo dir = new DirectoryInfo(dirPath);
            fileList = dir.GetFiles(@"*" + extName);
            foreach (FileInfo info in fileList)
            {
                arrList.Add(info.Name);
                //if (info.Name.StartsWith("YZ_", StringComparison.Ordinal))
                //{
                //    arrList.Add(info.Name);
                //}
                //string fileShortName = info.Name.Replace(".dll", "");
                //switch (info.Name.Replace(".dll", ""))
                //{
                //    case "CommonUtil":
                //        arrList.Add(fileShortName);
                //        break;
                //    case "WinFrmCtrlLib":
                //        arrList.Add(fileShortName);
                //        break;
                //    default:
                //        break;
                //}
            }
            return arrList;
        }

        /// <summary>
        ///  返回文件名|文件MD5Hash值
        /// </summary>
        /// <param name="fileList">文件名列表</param>
        /// <returns></returns>
        public static string FileMD5HashArray(ArrayList fileList)
        {
            string fileMD5HashArray = string.Empty;
            string fileName = string.Empty;
            string md5hash = string.Empty;
            for (int i=0; i < fileList.Count; i++)
            {
                fileName = fileList[i].ToString();
                md5hash = GetFileMD5Hash(fileName);
                fileMD5HashArray = fileName + "|" + md5hash + ",";
            }
            return fileMD5HashArray.TrimEnd(',');
        }

        #region 获取版本号
        /// <summary>
        ///  获取DLL文件的“文件名|文件版本“字符串
        /// </summary>
        /// <param name="fileList">文件列表</param>
        /// <returns></returns>
        public static string FileUtilDllVersion(ArrayList fileList)
        {
            if (fileList != null)
            {
                return FileNameAndVersion(fileList, @".dll");
            }
            else
                return string.Empty;
        }

        /// <summary>
        ///  获取“文件名|文件版本“字符串
        /// </summary>
        /// <param name="fileList">文件列表</param>
        /// <param name="ext">文件后缀名：.dll</param>
        /// <returns>fileName.ext|fileVersion,fileName.ext|fileVersion</returns>
        public static string FileNameAndVersion(ArrayList fileList, string ext)
        {
            string dllVersions = string.Empty;
            string fileName = string.Empty;
            string fileShortName = string.Empty;
            string fileVersion = string.Empty;
            for (int i = 0; i < fileList.Count; i++)
            {
                fileName = fileList[i].ToString();
                fileShortName = fileName.Replace(ext,"");
                //fileVersion = GetAssemblyVersion(fileShortName, ext);
                fileVersion = GetFileVersion(BaseDirectory() + "ClientUpdate\\", fileName);
                dllVersions =dllVersions + fileName + "|" + fileVersion + ",";
            }
            return dllVersions.TrimEnd(',');
        }
        /// <summary>
        /// 获取版本号：通过反射
        /// </summary>
        /// <param name="name">默认当前目录下的文件名称</param>
        /// <param name="ext">默认当前目录下的文件扩展名@".exe"</param>
        /// <returns></returns>
        public static string GetAssemblyVersion(string name,string ext)
        {
            byte[] filedata = File.ReadAllBytes(name + ext);
            return Assembly.Load(filedata).GetName().Version.ToString();
            #region 获取指定路径的文件版本号
            /**
             * 或者分解为如下方式，可获取指定路径的文件版本号，exe或dll
            string path = @""; //可指定文件的绝对路径
            Assembly assembly = Assembly.LoadFile(path); 
            AssemblyName assemblyName = assembly.GetName();
            Version version = assemblyName.Version;
            assemblyName.FullName
                version.Major
                    version.Minor
                         version.Revision
                             version.Build
             * */
            #endregion
        }

        /// <summary>
        /// 获取版本号：通过读取Assembly
        /// </summary>
        /// <returns></returns>
        public static string AssemblyFileVersion()
        {
            object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false);
            if (attributes.Length == 0)
            {
                return "";
            }
            else
            {
                return ((AssemblyFileVersionAttribute)attributes[0]).Version;
            }
        }
        #endregion 获取版本号

        #region 获取程序目录
        // 获取程序的基目录
        // 获取当前 Thread 的当前应用程序域的基目录，它由程序集冲突解决程序用来探测程序集。
        public static string BaseDirectory()
        {
            // X:\xxx\xxx\ (.exe文件所在的目录+"\")
            return AppDomain.CurrentDomain.BaseDirectory;
        }
　　  // 获取模块的完整路径
        // 获取新的 Process 组件并将其与当前活动的进程关联的主模块的完整路径，包含文件名(进程名)。
        public static string FileFullName()
        {
            // X:\xxx\xxx\xxx.exe (.exe文件所在的目录+.exe文件名)
　　      return Process.GetCurrentProcess().MainModule.FileName;
        }
　　// 获取和设置当前目录(该进程从中启动的目录)的完全限定目录。
        public static string CurrentDirectory()
        {
            // X:\xxx\xxx (.exe文件所在的目录)
　　      return Environment.CurrentDirectory;
        }
        // 获取应用程序的当前工作目录(这个不可靠)
        public static string CurrentAppDirectory()
        {
            // X:\xxx\xxx (.exe文件所在的目录)
　　      return Directory.GetCurrentDirectory();
        }
　　  // 获取和设置包括该应用程序的目录的名称。
        public static string ApplicationBase()
        {
            // X:\xxx\xxx\ (.exe文件所在的目录+"\")
　　      return AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
        }
        // 获取启动了应用程序的可执行文件的路径,，不包括可执行文件的名称。
        public static string StartupPath()
        {
            // X:\xxx\xxx (.exe文件所在的目录)
　　      return System.Windows.Forms.Application.StartupPath;
        }
　　  // 获取启动了应用程序的可执行文件的路径及文件名
        public static string ExecutablePath()
        {
            // X:\xxx\xxx\xxx.exe (.exe文件所在的目录+.exe文件名)
            return System.Windows.Forms.Application.ExecutablePath;
        }
        #endregion

    }
}
